﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using Wsq.Utils.DoNetFramework40.Socket;
using Wsq.Utils.DoNetFramework40.Socket.tools;
using MihaZupan;
using Org.BouncyCastle.Utilities.Net;
using MySql.Data.MySqlClient;

namespace PlayerParse
{
    internal class MyHttpServer : HttpServer
    {
        Dictionary<string, string> m3u8_filestr=new Dictionary<string, string>();
        Dictionary<string, string> ts_filebyte = new Dictionary<string, string>();
        string address = "127.0.0.1";
        string proxyAddress = "172.16.16.253";
        int proxyPort = 1080;
        HttpToSocks5Proxy proxy = null;
        string connectionString = "Server=your_server;Database=your_database;User ID=your_username;Password=your_password;";
        public MyHttpServer(int port, string wsPath = "/") : base(port, wsPath)
        {
            address = ConfigurationManager.AppSettings["Address"];
            this.port = port;
            string proxyAddress = ConfigurationManager.AppSettings["ProxyAddress"];
            int proxyPort = int.Parse(ConfigurationManager.AppSettings["ProxyPort"]);
            connectionString = $"Server={ConfigurationManager.AppSettings["DBAddress"]};Port={ConfigurationManager.AppSettings["DBPort"]};Database={ConfigurationManager.AppSettings["DBName"]};User ID={ConfigurationManager.AppSettings["DBUserID"]};Password={ConfigurationManager.AppSettings["DBPassword"]};";
            using (MySqlConnection conn=new MySqlConnection(connectionString))
            {
                conn.Open();
                Console.WriteLine("连接成功");
            }

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
            proxy = new HttpToSocks5Proxy(proxyAddress, proxyPort);
            
        }
        public override void handleRequest(HttpReadParse readParse, HttpResponse response)
        {
            if (readParse.HttpRequestMethed=="GET")
            {
                //Console.WriteLine(readParse.HttpRequestUrl);
                string urlpath= readParse.HttpRequestUrl.Split('?')[0];
                switch (urlpath)
                {
                    case "/dplayer":
                        dplayer(readParse, response);
                        break;
                    case "/m3u8":
                        m3u8(readParse, response);
                        break;
                    case "/proxy":
                        proxyurl(readParse, response);
                        break;
                    default:

                        if (m3u8_filestr.ContainsKey(readParse.HttpRequestUrl))
                        {
                            response.WriteM3u8(m3u8_filestr[readParse.HttpRequestUrl]);
                        }
                        else if (ts_filebyte.ContainsKey(readParse.HttpRequestUrl)) {
                            transTSFile(readParse, response);
                        }
                        else
                        {
                            response.WriteSuccess();
                        }
                        
                        break;
                }

            }
            if (readParse.HttpRequestMethed=="POST")
            {
                string urlpath = readParse.HttpRequestUrl.Split('?')[0];
                switch (urlpath)
                {
                    case "/getNeedTradingDay":
                        getNeedTradingDay(readParse, response);
                        break;
                    case "/hisHold":
                        hisHold(readParse, response);
                        break;
                    default:
                        response.WriteFailure();
                        break;
                }
            }
        }

        private void proxyurl(HttpReadParse readParse, HttpResponse response)
        {
            var reqparam = readParse.GetReqParam();
            string url = "";
            foreach (var param in reqparam)
            {
                if (param.Key == "url")
                {
                    url = param.Value;
                }
            }
            if (url!="")
            {
                // 解析原始URL
                Uri uri = new Uri(url);
                string resfirstLine = "";
                string reshead = "";
                byte[] rescontent = null;
                using (var proxyhandler = new HttpClientHandler { Proxy = proxy, UseProxy = true })
                {
                    using (HttpClient client = new HttpClient(proxyhandler, true))
                    {
                        HttpResponseMessage res = client.GetAsync(url).Result;

                        if (res.IsSuccessStatusCode)
                        {
                            resfirstLine = $"HTTP/{res.Version} {(int)res.StatusCode} {res.ReasonPhrase}\r\n";
                            reshead = res.Content.Headers.ToString();
                            rescontent = res.Content.ReadAsByteArrayAsync().Result;
                            
                        }
                        else
                        {
                            Console.WriteLine($"请求失败：{res.StatusCode}");
                        }
                    }
                }
                response.Write(resfirstLine);
                response.Write(reshead);
                response.Write("\r\n");
                response.Write(rescontent);
            }
            else
            {
                response.WriteFailure();
            }
            
        }

        private void m3u8(HttpReadParse readParse, HttpResponse response)
        {
            var reqparam = readParse.GetReqParam();
            string url = "";
            foreach (var param in reqparam)
            {
                if (param.Key == "url")
                {
                    url = param.Value;
                }
            }
            //m3u8链接转换
            // 解析原始URL
            Uri uri = new Uri(url);
            if (!m3u8_filestr.ContainsKey(uri.PathAndQuery))
            {
                string filestr = getM3u8FileStr(url);
                string newFilestr = "";
                //解析TS文件链接
                using (StringReader reader = new StringReader(filestr))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        Uri uriResult = null;
                        bool canparse = Uri.TryCreate(line, UriKind.Absolute, out uriResult);
                        bool isUrl = canparse && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
                        if (isUrl)
                        {
                            string surl = line;
                            string turl = "http://" + address + ":" + port + "" + uriResult.PathAndQuery;
                            newFilestr += turl + "\r\n";
                            if (!ts_filebyte.ContainsKey(uriResult.PathAndQuery))
                            {
                                ts_filebyte.Add(uriResult.PathAndQuery, surl);
                            }
                        }
                        else
                        {
                            newFilestr += line + "\r\n";
                        }

                    }
                }
                m3u8_filestr.Add(uri.PathAndQuery, newFilestr);
            }
            response.WriteM3u8(m3u8_filestr[uri.PathAndQuery]);
        }

        private void getNeedTradingDay(HttpReadParse readParse, HttpResponse response)
        {
            throw new NotImplementedException();
        }

        private void hisHold(HttpReadParse readParse, HttpResponse response)
        {
            string hisholdstr = readParse.HttpBodyText;
            
        }

        private void transTSFile(HttpReadParse readParse, HttpResponse response)
        {
            byte[] responseBody = { };
            using (var proxyhandler = new HttpClientHandler { Proxy = proxy, UseProxy = true })
            {
                using (HttpClient client = new HttpClient(proxyhandler))
                {
                    HttpResponseMessage resp = client.GetAsync(ts_filebyte[readParse.HttpRequestUrl]).Result;

                    if (resp.IsSuccessStatusCode)
                    {
                        responseBody = resp.Content.ReadAsByteArrayAsync().Result;
                        //Console.WriteLine(responseBody);
                    }
                    else
                    {
                        Console.WriteLine($"请求失败：{resp.StatusCode}");
                    }
                }
            }
            
            response.WriteTS(responseBody);
        }

        private void dplayer(HttpReadParse readParse, HttpResponse response)
        {
            var reqparam = readParse.GetReqParam();
            string url = "";
            foreach (var param in reqparam)
            {
                if (param.Key=="url")
                {
                    url = param.Value;
                }
            }
            
            

            //m3u8链接转换
            // 解析原始URL
            Uri uri = new Uri(url);
            // 构建新的URL
            string newUrl = "http://"+address+":"+port+"" + uri.PathAndQuery;
            //m3u8文件获取
            if (!m3u8_filestr.ContainsKey(uri.PathAndQuery)) {
                string filestr = getM3u8FileStr(url);
                string newFilestr = "";
                //解析TS文件链接
                using (StringReader reader = new StringReader(filestr))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        Uri uriResult=null;
                        bool canparse=Uri.TryCreate(line, UriKind.Absolute, out uriResult);
                        bool isUrl = canparse && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
                        if (isUrl)
                        {
                            string surl = line;
                            string turl= "http://"+address+":"+port+"" + uriResult.PathAndQuery;
                            newFilestr += turl + "\r\n";
                            if (!ts_filebyte.ContainsKey(uriResult.PathAndQuery))
                            {
                                ts_filebyte.Add(uriResult.PathAndQuery, surl);
                            }
                        }
                        else
                        {
                            newFilestr += line + "\r\n";
                        }
                        
                    }
                }
                m3u8_filestr.Add(uri.PathAndQuery, newFilestr);
                

            }

            response.WriteHtml("<meta content=\"width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no\" id=\"viewport\" name=\"viewport\">\r\n</head>\r\n<body marginwidth=\"0\" marginheight=\"0\" style=\"position:absolute;width:100%;top:0;bottom:0;backgroung:#000\">\r\n<link rel=\"stylesheet\" href=\"./DPlayer.min.css\">\r\n<script src=\"./jquery.min.js\"></script>\r\n<div id=\"player1\"></div>\r\n<script type=\"text/javascript\" src=\"//www.dplayer.top/hls.p2p.js\"></script>\r\n<script type=\"text/javascript\" src=\"//www.dplayer.top/DPlayer.min.js\" charset=\"utf-8\"></script>\r\n<script>\r\nvar dp = new DPlayer({\r\n    element: document.getElementById('player1'),\r\n    video: {\r\n        url: \""+ newUrl + "\"\r\n    }\r\n});\r\ndp.play();\r\n</script>\r\n<!-- Google tag (gtag.js) -->\r\n<script async src=\"https://www.googletagmanager.com/gtag/js?id=G-SZE06HRHGD\"></script>\r\n<script>\r\n  window.dataLayer = window.dataLayer || [];\r\n  function gtag(){dataLayer.push(arguments);}\r\n  gtag('js', new Date());\r\n\r\n  gtag('config', 'G-SZE06HRHGD');\r\n</script>\r\n</body>\r\n</html>");
        }

        private string getM3u8FileStr(string url) 
        {
            string responseBody="";




            using (var proxyhandler = new HttpClientHandler { Proxy = proxy, UseProxy = true })
            {
                using (HttpClient client = new HttpClient(proxyhandler, true))
                {
                    HttpResponseMessage response = client.GetAsync(url).Result;

                    if (response.IsSuccessStatusCode)
                    {
                        responseBody = response.Content.ReadAsStringAsync().Result;
                        //Console.WriteLine(responseBody);
                    }
                    else
                    {
                        Console.WriteLine($"请求失败：{response.StatusCode}");
                    }
                }
            } 
            
            return responseBody;
        }

        public override void WsConnected(SocketAsyncEventArgs e)
        {
            throw new NotImplementedException();
        }

        public override void WsDataOn(byte[] data, SocketAsyncEventArgs e)
        {
            throw new NotImplementedException();
        }

        public override void WsDisConnected(SocketAsyncEventArgs e)
        {
            throw new NotImplementedException();
        }
    }
}
